package app

import (
	"log"
	"net/http"

	"gitee.com/xuender/ds/pb"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"google.golang.org/protobuf/proto"
)

// DisplayCtrl 显示控制.
type DisplayCtrl struct {
	upGrader websocket.Upgrader
	cs       *ConfigService
	ws       *WebService
}

// NewDisplayCtrl 新显示控制.
func NewDisplayCtrl(
	cs *ConfigService,
	ws *WebService,
) *DisplayCtrl {
	for _, w := range cs.Webs {
		ws.GetPage(w.Url)
	}

	return &DisplayCtrl{
		cs: cs,
		ws: ws,
		upGrader: websocket.Upgrader{
			CheckOrigin: func(r *http.Request) bool {
				return true
			},
		},
	}
}

// Display 显示.
func (c *DisplayCtrl) Display(ctx *gin.Context) {
	ctx.HTML(http.StatusOK, "assets/display.tmpl", gin.H{
		"id": ctx.Param("id"),
	})
}

// WebSocket 链接.
func (c *DisplayCtrl) WebSocket(ctx *gin.Context) {
	// 升级get请求为webSocket协议
	ws, err := c.upGrader.Upgrade(ctx.Writer, ctx.Request, nil)
	if err != nil {
		return
	}
	defer ws.Close()

	for {
		// 读取ws中的数据
		mt, message, err := ws.ReadMessage()
		if err != nil {
			break
		}

		if mt != websocket.BinaryMessage {
			log.Println(string(message))

			continue
		}

		msg := &pb.Msg{}
		if err := proto.Unmarshal(message, msg); err != nil {
			log.Println(err)

			continue
		}

		// 发送消息
		if bs, err := proto.Marshal(c.newMsg(msg)); err != nil {
			log.Println(err)
		} else if err := ws.WriteMessage(mt, bs); err != nil {
			break
		}
	}
}

func (c *DisplayCtrl) newMsg(msg *pb.Msg) *pb.Msg {
	var err error

	m := &pb.Msg{
		Code: msg.Code,
	}
	// 请求显示屏
	if msg.Code == DISPLAY {
		if m.Display, err = c.cs.GetDisplay(msg.Id); err != nil {
			m.Code = ERROR
			m.Error = err.Error()
		}
	}
	// 请求页面
	if msg.Code == PAGE {
		if m.Page, err = c.cs.GetPage(msg.Id); err != nil {
			m.Code = ERROR
			m.Error = err.Error()
		}
	}
	// 请求区块
	if msg.Code == BLOCK {
		if m.Block, err = c.cs.GetBlock(msg.Id); err != nil {
			m.Code = ERROR
			m.Error = err.Error()
		}
	}
	// Images
	if msg.Code == IMAGES {
		if m.Images, err = c.cs.GetImages(msg.Id); err != nil {
			m.Code = ERROR
			m.Error = err.Error()
		}
	}
	// Web
	if msg.Code == WEB {
		if m.Web, err = c.cs.GetWeb(msg.Id); err != nil {
			m.Code = ERROR
			m.Error = err.Error()
		} else {
			m.Web.Image, m.Web.Width, m.Web.Height = Png2RGBA(c.ws.Screenshot(m.Web.Url, m.Web.Selector))
		}
	}

	return m
}
